<template>
  <div>
    <div class="title">
      综合监控
      <div>
        <button ref="playSound" @click="playSound">声音</button>
        <button @click="set">设置</button>
      </div>
    </div>
    <div v-for="client in data" class="client clientWidth">
      <div>
        <input type="text" v-model="client.sort" style="width: 20px;" @change="exeUpdateSort(client.name,client.sort)">
        <span v-text="client.name" :style="{color:client.state==1?'green':'red'}"
              style="font-weight: bold;cursor: pointer;" @click="goInfo(client.name,client,'client')"></span>
        <span v-if="client.computer && client.computer.cpu" v-text="'CPU:'+roundNumber(client.computer.cpu.usage)+'%'"
              class="ml"
              :style="{color:client.computer.cpu.warning?'orange':'green'}"
              @click="goInfo(client.name,client.computer.cpu,'')"></span>
        <span v-if="client.computer && client.computer.mem" v-text="'内存:'+roundNumber(client.computer.mem.usage)+'%'"
              class="ml"
              :style="{color:client.computer.mem.warning?'orange':'green'}"
              @click="goInfo(client.name,client.computer.mem,'')"></span>
      </div>
      <hr class="clear">
      <div v-show="client.sysFiles && client.sysFiles.length>0">
        <div class="fml">磁盘：</div>
        <div v-for="item in client.sysFiles" class="fml">
          <span :style="{color:item.warning?'orange':'green'}" @click="goInfo(client.name,item,'')">
            <span v-text="item.dirName"></span>
            <span v-text="'  '+roundNumber(item.usage)+'%'"></span>
          </span>
        </div>
        <hr class="clear">
      </div>
      <div v-show="client.serviceVos && client.serviceVos.length>0">
        <div class="fml">服务：</div>
        <div v-for="item in client.serviceVos" class="fml" @click="goInfo(client.name,item,'service')">
          <span v-text="item.name" :style="{color:item.state=='运行中'?'green':'red'}"></span>
        </div>
        <hr class="clear">
      </div>
      <div v-show="client.batVos && client.batVos.length>0">
        <div class="fml">程序：</div>
        <div v-for="item in client.batVos" class="fml" @click="goInfo(client.name,item,'bat')">
          <span v-text="item.name" :style="{color:item.state=='运行中'?'green':'red'}"></span>
        </div>
        <hr class="clear">
      </div>
      <div v-show="client.tomcatVos && client.tomcatVos.length>0">
        <div class="fml">tom：</div>
        <div v-for="item in client.tomcatVos" class="fml" @click="goInfo(client.name,item,'tomcat')">
          <span v-text="item.name" :style="{color:item.state==1?(item.warning?'orange':'green'):'red'}"></span>
        </div>
        <hr class="clear">
      </div>
      <div v-show="client.jarVos && client.jarVos.length>0">
        <div class="fml">jar：</div>
        <div v-for="item in client.jarVos" class="fml" @click="goInfo(client.name,item,'jar')">
          <span v-text="item.name" :style="{color:item.state==1?(item.warning?'orange':'green'):'red'}"></span>
        </div>
        <hr class="clear">
      </div>
    </div>
    <div :style="{display:infoOpen?'block':'none'}" class="dialog" @click="infoOpen=cmDing" :key="dialogKey">
      <div v-if="!cmDing" class="info" @click.stop>
        <div class="head">
          <span v-text="info.name"></span>
          <button @click="infoOpen=false" style="float: right;cursor: pointer;">关闭</button>
        </div>
        <div class="content">
          <div class="tabTitle">
            <button :style="{color:tab=='info'?'red':'black'}" @click="tab='info'">信息</button>
            <button v-show="infoType=='bat' && info.name=='nginx'" :style="{color:tab=='config'?'red':'black'}"
                    @click="nginxQuery">配置文件
            </button>
            <button v-show="infoType=='tomcat'|| infoType=='jar'" :style="{color:tab=='files'?'red':'black'}"
                    @click="fileQuery(info.logPath)">日志文件
            </button>
            <button v-show="infoType=='client'" :style="{color:tab=='files'?'red':'black'}"
                    @click="fileQuery(info.computer.sys.userDir+'\\logs')">日志文件
            </button>
            <button v-show="tab=='file'" :style="{color:tab=='file'?'red':'black'}" v-text="readFile.name">
            </button>
          </div>
          <div class="tabContent">
            <div v-show="tab=='info'" class="files">
              <vue-json-pretty :data="info"></vue-json-pretty>
            </div>
            <div v-show="tab=='config'">
              <textarea v-model="nginxValue" rows="29" style="width: 95%;"></textarea>
            </div>
            <div v-show="tab=='files'" class="files">
              <div v-for="file0 in logFiles" class="file">
                <div v-text="file0.name" @click="openFile(file0)"
                     :style="{float: 'left',color:file0.type=='路径'?'blue':'black'}"></div>
                <div style="float: right;width: 150px;">
                  <button v-show="file0.type=='文件'" @click="downFile(file0)">下载</button>
                  <button v-show="file0.type=='路径'" @click="openFile(file0)">展开</button>
                  <button v-show="file0.type=='文件'" @click="fileRead(20,file0)">预览</button>
                </div>
                <div v-text="file0.lastModifiedDate" style="float: right;margin-right: 50px;"></div>
                <div v-text="file0.type" style="float: right;margin-right: 50px;"></div>
                <div v-text="file0.size" style="float: right;margin-right: 50px;"></div>
                <div class="clear" style="border-top: 1px dotted #cccccc;"></div>
                <div v-show="file0.children && file0.show">
                  <div v-for="file1 in file0.children" class="file">
                    <div v-text="file1.name" @click="openFile(file1)"
                         :style="{float: 'left',color:file1.type=='路径'?'blue':'black'}"></div>
                    <div style="float: right;width: 150px;">
                      <button v-show="file1.type=='文件'" @click="downFile(file1)">下载</button>
                      <button v-show="file1.type=='文件'" @click="fileRead(20,file1)">预览</button>
                    </div>
                    <div v-text="file1.lastModifiedDate" style="float: right;margin-right: 50px;"></div>
                    <div v-text="file1.type" style="float: right;margin-right: 50px;"></div>
                    <div v-text="file1.size" style="float: right;margin-right: 50px;"></div>
                    <div class="clear" style="border-top: 1px dotted #cccccc;"></div>
                  </div>
                </div>
                <div class="clear" style="border-top: 1px dotted #cccccc;"></div>
              </div>
            </div>
            <div v-show="tab=='file'" class="files">
              <div>
                <p v-for="item in fileLines" v-text="item" style="border-bottom: 1px dashed #cccccc;"></p>
              </div>
            </div>
          </div>
        </div>
        <div class="foot">
          <button v-show="infoType=='tomcat'" @click="exeCmd('restart')">重启</button>
          <button v-show="infoType=='tomcat'" @click="exeCmd('start')">启动</button>
          <button v-show="infoType=='tomcat'" @click="exeCmd('stop')">停止</button>
          <button v-show="infoType=='service'" @click="exeCmd('restart')">重启</button>
          <button v-show="infoType=='service'" @click="exeCmd('start')">启动</button>
          <button v-show="infoType=='service' " @click="exeCmd('stop')">停止</button>
          <button v-show="infoType=='jar'" @click="exeCmd('restart')">重启</button>
          <button v-show="infoType=='bat'" @click="exeCmd('restart')">重启</button>
          <button v-show="tab=='config'" @click="exeCmd('nginxEdit')">修改保存</button>
          <button v-show="tab=='config'" @click="exeCmd('nginxReload')">重新加载</button>
          <button v-show="tab=='file'" @click="fileRead(10)">最新10行</button>
          <button v-show="tab=='file'" @click="fileRead(20)">最新20行</button>
          <button v-show="tab=='file'" @click="fileRead(50)">最新50行</button>
          <button v-show="tab=='file'" @click="fileRead(100)">最新100行</button>
        </div>
      </div>
      <div v-else class="cmDing" @click.stop>执行中...</div>
    </div>
  </div>
</template>

<script>
import VueJsonPretty from 'vue-json-pretty/lib/vue-json-pretty.js'
import 'vue-json-pretty/lib/styles.css';
import {warningList} from "@/api/warning"
import {getInfo, goCmd, updateSort} from "@/api/index"
import {compareDates, deepClone, playSineWave} from "@/utils";

export default {
  name: "Index",
  components: {VueJsonPretty},
  data() {
    return {
      timer: null,
      warning: [],
      data: [],
      clientName: "",
      info: {},
      infoOpen: false,
      dialogKey: Math.random(),
      cmDing: false,
      tab: "info",
      infoType: "",
      filePath: "",
      nginxValue: "",
      logFiles: [],
      readFile: {},
      readFileLine: 20,
      fileLines: [],
    };
  },
  created() {
    warningList().then(res => {
      this.warning = res.data;
      this.queryData();
    })
  },
  mounted() {
    this.startTimer();
  },
  methods: {
    startTimer() {
      this.timer = setInterval(() => {
        this.queryData();
      }, 10000);
    },
    stopTimer() {
      if (this.timer) {
        clearInterval(this.timer);
        this.timer = null;
      }
    },
    queryData() {
      getInfo().then(res => {
        this.data = res.data.sort((a, b) => a.sort - b.sort);
        this.fitWarning();
      })
    },
    fitWarning() {
      let flag = false;
      for (let i = 0; i < this.data.length; i++) {
        flag = (this.data[i].state == 0 ? true : flag);
        this.data[i].tomcatVos.forEach(item => flag = (item.state == 0 ? true : flag));
        this.data[i].jarVos.forEach(item => flag = (item.state == 0 ? true : flag));
        this.data[i].serviceVos.forEach(item => flag = (item.state == "停止中" ? true : flag));
        this.data[i].batVos.forEach(item => flag = (item.state == "停止中" ? true : flag));
        for (let j = 0; j < this.warning.length; j++) {
          if (this.data[i].name == this.warning[j].client) {
            let arrTarget = this.warning[j].target.split(".")
            let d = this.data[i];
            let dp = this.data[i];
            for (let t = 0; t < arrTarget.length; t++) {
              if (t < arrTarget.length - 1) {
                dp = dp[arrTarget[t]];
              }
              d = d[arrTarget[t]];
            }
            dp.warning = false;
            if (typeof d == "number" && d > this.warning[j].number) {
              dp.warning = true;
              flag = true;
            }
            if (typeof d == "string" && d.replace(/%/g, "") > this.warning[j].number) {
              dp.warning = true;
              flag = true;
            }
          }
        }
      }
      if (flag) {
        this.$refs.playSound.click();
      }
    },
    exeUpdateSort(name, sort) {
      updateSort({clientName: name, sort: sort});
    },
    goInfo(clientName, info, infoType) {
      this.info = deepClone(info);
      this.clientName = clientName;
      this.infoOpen = true;
      this.tab = 'info';
      this.infoType = infoType;
      this.nginxValue = "";
      this.logFiles = [];
    },
    exeCmd(cmdEnum) {
      this.cmDing = true;
      this.stopTimer();
      goCmd({
        clientName: this.clientName,
        serverName: this.info.name,
        typeEnum: this.infoType,
        cmdEnum: cmdEnum,
        nginxValue: this.nginxValue
      }).then(res => {
        if (cmdEnum == "nginxQuery") {
          this.nginxValue = res.msg;
        } else if (cmdEnum == 'nginxEdit') {
          alert(res.msg);
        } else {
          alert(res.msg);
          this.infoOpen = false;
          this.queryData();
        }
        this.cmDing = false;
        this.startTimer();
      }).catch(e => {
        alert(e);
        this.infoOpen = false;
        this.cmDing = false;
      })
    },
    nginxQuery() {
      this.tab = 'config';
      this.exeCmd("nginxQuery")
    },
    fileQuery(path) {
      this.tab = 'files';
      goCmd({
        clientName: this.clientName,
        serverName: this.info.name,
        typeEnum: "queryFiles",
        filePath: path
      }).then(res => {
        this.logFiles = JSON.parse(res.msg);
        this.logFiles.sort((a, b) => compareDates(new Date(b.lastModifiedDate), new Date(a.lastModifiedDate)));
      }).catch(e => {
        alert(e);
        this.infoOpen = false;
      });
    },
    fileRead(line, file) {
      this.tab = 'file';
      if (file) {
        this.readFile = file;
      }
      this.fileLines = [];
      goCmd({
        clientName: this.clientName,
        serverName: this.info.name,
        typeEnum: "readFile",
        number: line,
        filePath: this.readFile.path
      }).then(res => {
        this.fileLines = JSON.parse(res.msg);
      }).catch(e => {
        alert(e);
        this.infoOpen = false;
      });
    },
    openFile(file) {
      if (file.type == '路径') {
        file.show = file.show ? false : true;
        file.children = file.children.sort((a, b) => compareDates(new Date(b.lastModifiedDate), new Date(a.lastModifiedDate)));
        this.dialogKey = Math.random();
      }
    },
    downFile(file) {
      if (file.type == '文件') {
        goCmd({
          clientName: this.clientName,
          serverName: this.info.name,
          typeEnum: "downloadFile",
          filePath: file.path
        }).then(res => {
          window.open(res.msg);
        }).catch(e => {
          alert(e);
          this.infoOpen = false;
        });
      } else {
        this.openFile(file);
      }
    },
    playSound() {
      playSineWave();
    },
    set() {
      window.open("set")
    },
  },
  beforeDestroy() {
    this.stopTimer();
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
.title {
  text-align: center;
  height: 40px;
  line-height: 40px;
  font-size: 20px;
  font-weight: bold;
  border-bottom: 1px solid #cccccc;

  div {
    position: absolute;
    right: 10px;
    top: -3px;
  }
}

button {
  margin: 0 10px;
}

@media (max-width: 800px) {
  .clientWidth {
    width: 90%;
    margin: 10px auto;
  }
}

@media (min-width: 800px) and (max-width: 1000px) {
  .clientWidth {
    width: 45%;
    margin: 10px;
    float: left;
  }
}

@media (min-width: 1000px) and (max-width: 1200px) {
  .clientWidth {
    width: 30%;
    margin: 10px;
    float: left;
  }
}

@media (min-width: 1200px) {
  .clientWidth {
    width: 22%;
    margin: 10px;
    float: left;
  }
}

.client {
  border: 1px solid #cccccc;
  padding: 10px;
}

.clear {
  clear: both;
}

.ml {
  margin-left: 10px;
  cursor: pointer;
}

.fml {
  float: left;
  margin-left: 10px;
  cursor: pointer;
}

.dialog {
  background-color: rgba(0, 0, 0, 0.2);
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 9999;

  .info {
    width: 80%;
    height: 600px;
    background-color: #FFFFFF;
    margin: 100px auto 0;
    border-radius: 20px;
    padding: 20px;
    position: relative;

    .head {
      width: 100%;
      border-bottom: 1px solid #cccccc;
      height: 40px;
      line-height: 40px;
    }

    .content {
      height: 520px;
      overflow: auto;

      .tabTitle {
        padding: 10px;
      }

      textarea {
        width: 90%;
      }

      .files {
        border: 1px solid #cccccc;
        height: 430px;
        overflow: auto;
        padding: 10px;
      }

      .file {
        margin: 10px 0 10px 20px;
        cursor: pointer;
      }
    }

    .foot {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      border-top: 1px solid #cccccc;
      height: 60px;
      line-height: 40px;
      text-align: center;

      span {
        cursor: pointer;
        margin: 0 10px;
        border: 1px solid #cccccc;
        padding: 0 5px;
        border-radius: 4px;
      }
    }
  }

  .cmDing {
    margin-top: 100px;
    font-size: 30px;
    text-align: center;
    color: #ffffff;
  }
}
</style>
